/*

	err := ModelOpen()
	if err != nil {
		return
	}
	defer ModelClose()

*/

package main

import (
	"log"
	"errors"
	
	"database/sql"
	_ "github.com/mattn/go-sqlite3"
)

var db *sql.DB

func ModelOpen() error {
	dbo, err := sql.Open("sqlite3", "../testing/textpunk.db")
	if err != nil {
		log.Fatal(err)
		return errors.New("Could not open database")
	}
	
	db = dbo

	err = db.Ping()
	if err != nil {
		log.Fatal(err)
		return errors.New("Could not ping database")
	}

	return nil
}

func ModelClose() {
	db.Close()
}

type Board struct {
	Id        int       `json:"id"`
	Name      string    `json:"board_title"`
}

type Boards []Board

type Thread struct {
	Id        int       `json:"id"`
	Name      string    `json:"thread_title"`
}

type Threads []Thread

type Post struct {
	Id        int       `json:"id"`
	Content   string    `json:"post_content"`
}

type Posts []Post

// TODO what if these functions are called before the db is initialized?

func ModelBoards() Boards {
	rows, err := db.Query("SELECT id, board_title FROM boards")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	bs := make(Boards, 0)
	
	for rows.Next() {
		var id int
		var board_title string
		rows.Scan(&id, &board_title)
		bs = append(bs, Board{Id: id, Name: board_title})
	}
	
	return bs
}

func ModelThreads(board_id int) Threads {
	stmt, err := db.Prepare("SELECT id, thread_title FROM threads WHERE board_id = ?")
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close()
	
	rows, err := stmt.Query(board_id)
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	
	ts := make(Threads, 0)
	
	for rows.Next() {
		var id int
		var thread_title string
		rows.Scan(&id, &thread_title)
		ts = append(ts, Thread{Id: id, Name: thread_title})
	}
	
	return ts
}

func ModelPosts(board_id int, thread_id int) Posts {
	stmt, err := db.Prepare("SELECT id, post_content FROM posts WHERE board_id = ? AND thread_id = ?")
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close()
	
	rows, err := stmt.Query(board_id, thread_id)
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	
	ps := make(Posts, 0)
	
	for rows.Next() {
		var id int
		var post_content string
		rows.Scan(&id, &post_content)
		ps = append(ps, Post{Id: id, Content: post_content})
	}
	
	return ps
}
